"use client"

import { useState, useCallback, useEffect, useMemo } from "react"
import { useRouter } from "next/navigation"
import ReactFlow, {
  Node,
  Edge,
  addEdge,
  Background,
  Controls,
  MiniMap,
  Connection,
  useNodesState,
  useEdgesState,
  MarkerType,
  Panel,
} from "reactflow"
import "reactflow/dist/style.css"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Badge } from "@/components/ui/badge"
import { Textarea } from "@/components/ui/textarea"
import { Separator } from "@/components/ui/separator"
import { useToast } from "@/hooks/use-toast"
import { mockData } from "@/lib/mock-data"
import {
  Save,
  Play,
  Download,
  Copy,
  Eye,
  Edit3,
  Info,
  Code2,
} from "lucide-react"

import { CustomNode } from "@/components/flow-nodes/custom-node"
import { NodeParameterEditor, ParameterList } from "@/components/node-parameter-editor"
import { difyNodeConfigs, cozeNodeConfigs, iconMap, type NodeConfig } from "@/lib/node-configs"
import { generateLangGraphCodeV2 } from "@/lib/langgraph-generator-v2"

const nodeTypes = {
  custom: CustomNode,
}

interface WorkflowBuilderV3Props {
  workflowId?: string
  mode?: "edit" | "view"
}

export function WorkflowBuilderV3({ workflowId, mode = "edit" }: WorkflowBuilderV3Props) {
  const router = useRouter()
  const { toast } = useToast()
  const [isLoading, setIsLoading] = useState(true)
  const [workflowName, setWorkflowName] = useState("未命名工作流")
  const [workflowType, setWorkflowType] = useState<"dify" | "coze" | "langgraph">("dify")
  const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null)
  const [langGraphCode, setLangGraphCode] = useState("")
  const [viewMode, setViewMode] = useState<"edit" | "view">(mode)

  const [nodes, setNodes, onNodesChange] = useNodesState([])
  const [edges, setEdges, onEdgesChange] = useEdgesState([])

  // Load workflow data
  useEffect(() => {
    const timer = setTimeout(() => {
      // 首先尝试从 sessionStorage 恢复状态（从代码查看页返回时）
      const savedNodes = sessionStorage.getItem("workflow_builder_nodes")
      const savedEdges = sessionStorage.getItem("workflow_builder_edges")
      const savedName = sessionStorage.getItem("workflow_builder_name")

      if (savedNodes && savedEdges) {
        // 恢复状态
        try {
          const parsedNodes = JSON.parse(savedNodes)
          const parsedEdges = JSON.parse(savedEdges)

          // 恢复 onDelete 回调
          const nodesWithCallback = parsedNodes.map((node: Node) => ({
            ...node,
            data: {
              ...node.data,
              onDelete: handleDeleteNode,
            },
          }))

          setNodes(nodesWithCallback)
          setEdges(parsedEdges)
          if (savedName) setWorkflowName(savedName)

          // 清理 sessionStorage
          sessionStorage.removeItem("workflow_builder_nodes")
          sessionStorage.removeItem("workflow_builder_edges")
          sessionStorage.removeItem("workflow_builder_name")
        } catch (error) {
          console.error("Failed to restore workflow builder state:", error)
        }
        setIsLoading(false)
      } else if (workflowId) {
        // 从 mockData 加载
        try {
          const workflow = mockData.getWorkflow(workflowId)
          if (workflow) {
            setWorkflowName(workflow.name)
            setWorkflowType(workflow.type)

            // Convert old format to React Flow format
            const flowNodes: Node[] =
              workflow.nodes?.map((node) => ({
                id: node.id,
                type: "custom",
                position: { x: node.x || 0, y: node.y || 0 },
                data: {
                  label: node.label,
                  type: node.type,
                  iconName: node.config?.iconName,
                  config: node.config,
                  parameterValues: node.config?.parameterValues || {},
                  onDelete: handleDeleteNode,
                },
              })) || []

            const flowEdges: Edge[] =
              workflow.edges?.map((edge) => ({
                id: edge.id,
                source: edge.source,
                target: edge.target,
                type: "smoothstep",
                animated: true,
                markerEnd: {
                  type: MarkerType.ArrowClosed,
                },
              })) || []

            setNodes(flowNodes)
            setEdges(flowEdges)
            setLangGraphCode(workflow.code || getDefaultLangGraphCode())
          }
        } catch (error) {
          console.error("Error loading workflow:", error)
          setLangGraphCode(getDefaultLangGraphCode())
        }
        setIsLoading(false)
      } else {
        setLangGraphCode(getDefaultLangGraphCode())
        setIsLoading(false)
      }
    }, 0)

    return () => clearTimeout(timer)
  }, [workflowId])

  const nodeConfigs = workflowType === "dify" ? difyNodeConfigs : cozeNodeConfigs

  function getDefaultLangGraphCode() {
    return `from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
from operator import add

class State(TypedDict):
    messages: Annotated[list[str], add]

def process_input(state: State):
    """处理输入节点"""
    return {"messages": ["Input processed"]}

def llm_node(state: State):
    """LLM 处理节点"""
    response = "LLM response based on: " + str(state["messages"])
    return {"messages": [response]}

def output_node(state: State):
    """输出节点"""
    return {"messages": ["Output: " + state["messages"][-1]]}

# 创建工作流图
workflow = StateGraph(State)

# 添加节点
workflow.add_node("input", process_input)
workflow.add_node("llm", llm_node)
workflow.add_node("output", output_node)

# 设置入口点
workflow.set_entry_point("input")

# 添加边（连接节点）
workflow.add_edge("input", "llm")
workflow.add_edge("llm", "output")
workflow.add_edge("output", END)

# 编译工作流
app = workflow.compile()`
  }

  const onConnect = useCallback(
    (params: Connection) => {
      setEdges((eds) =>
        addEdge(
          {
            ...params,
            type: "smoothstep",
            animated: true,
            markerEnd: {
              type: MarkerType.ArrowClosed,
            },
          },
          eds,
        ),
      )
    },
    [setEdges],
  )

  const onDragOver = useCallback((event: React.DragEvent) => {
    event.preventDefault()
    event.dataTransfer.dropEffect = "move"
  }, [])

  const onDrop = useCallback(
    (event: React.DragEvent) => {
      event.preventDefault()

      const nodeConfigStr = event.dataTransfer.getData("application/reactflow")
      if (!nodeConfigStr) return

      const nodeConfig: NodeConfig = JSON.parse(nodeConfigStr)

      const position = {
        x: event.clientX - 200,
        y: event.clientY - 100,
      }

      const newNode: Node = {
        id: `${nodeConfig.type}-${Date.now()}`,
        type: "custom",
        position,
        data: {
          label: nodeConfig.label,
          type: nodeConfig.type,
          iconName: nodeConfig.iconName,
          config: nodeConfig,
          parameterValues: {},
          onDelete: handleDeleteNode,
        },
      }

      setNodes((nds) => nds.concat(newNode))
      toast({
        title: "节点已添加",
        description: `${nodeConfig.label} 已添加到画布`,
      })
    },
    [setNodes, toast],
  )

  const handleDeleteNode = useCallback(
    (nodeId: string) => {
      setNodes((nds) => nds.filter((node) => node.id !== nodeId))
      setEdges((eds) => eds.filter((edge) => edge.source !== nodeId && edge.target !== nodeId))
      if (selectedNodeId === nodeId) {
        setSelectedNodeId(null)
      }
      toast({
        title: "节点已删除",
        description: "节点及其连接已从画布中移除",
      })
    },
    [setNodes, setEdges, selectedNodeId, toast],
  )

  const handleSave = () => {
    const workflowData = {
      name: workflowName,
      type: workflowType,
      nodes: nodes.map((node) => ({
        id: node.id,
        type: node.data.type,
        label: node.data.label,
        x: node.position.x,
        y: node.position.y,
        config: {
          iconName: node.data.iconName,
          parameterValues: node.data.parameterValues,
        },
      })),
      edges: edges.map((edge) => ({
        id: edge.id,
        source: edge.source,
        target: edge.target,
      })),
      code: workflowType === "langgraph" ? langGraphCode : undefined,
    }

    if (workflowId) {
      mockData.updateWorkflow(workflowId, workflowData)
      toast({
        title: "保存成功",
        description: "工作流已更新",
      })
    } else {
      mockData.addWorkflow({
        ...workflowData,
        status: "draft",
        lastRun: "从未运行",
        createdAt: new Date().toISOString().split("T")[0],
      })
      toast({
        title: "保存成功",
        description: "新工作流已创建",
      })
    }
  }

  const handleTest = () => {
    toast({
      title: "测试运行中",
      description: "工作流正在执行测试...",
    })
    setTimeout(() => {
      toast({
        title: "测试完成",
        description: "工作流执行成功",
      })
    }, 2000)
  }

  const handleExportCode = () => {
    const blob = new Blob([langGraphCode], { type: "text/plain" })
    const url = URL.createObjectURL(blob)
    const a = document.createElement("a")
    a.href = url
    a.download = `${workflowName.replace(/\s+/g, "_")}_workflow.py`
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
    URL.revokeObjectURL(url)
    toast({
      title: "导出成功",
      description: "LangGraph 代码已下载",
    })
  }

  const handleCopyCode = async () => {
    try {
      await navigator.clipboard.writeText(langGraphCode)
      toast({
        title: "复制成功",
        description: "代码已复制到剪贴板",
      })
    } catch (err) {
      toast({
        title: "复制失败",
        description: "请手动复制代码",
        variant: "destructive",
      })
    }
  }

  const handleViewGeneratedCode = () => {
    // 生成分层架构代码（使用V2版本）
    const code = generateLangGraphCodeV2(nodes, edges, nodeConfigs)

    // 保存当前 Workflow Builder 状态，以便返回时恢复
    sessionStorage.setItem("workflow_builder_nodes", JSON.stringify(nodes))
    sessionStorage.setItem("workflow_builder_edges", JSON.stringify(edges))
    sessionStorage.setItem("workflow_builder_name", workflowName)

    // 保存生成的代码到 sessionStorage
    sessionStorage.setItem("langgraph_generated_code_v2", JSON.stringify(code))
    sessionStorage.setItem("langgraph_source_type", "workflow")
    sessionStorage.setItem("langgraph_source_name", workflowName)

    // 导航到代码查看页面
    router.push("/dashboard/code-viewer")

    toast({
      title: "代码已生成",
      description: `已生成包含 ${code.layers.length} 层架构、${code.summary.fileCount} 个文件`,
    })
  }

  const onDragStart = (event: React.DragEvent, config: NodeConfig) => {
    event.dataTransfer.setData("application/reactflow", JSON.stringify(config))
    event.dataTransfer.effectAllowed = "move"
  }

  const selectedNode = useMemo(() => {
    return nodes.find((node) => node.id === selectedNodeId)
  }, [nodes, selectedNodeId])

  const selectedNodeConfig = useMemo(() => {
    if (!selectedNode) return null
    return nodeConfigs.find((config) => config.type === selectedNode.data.type)
  }, [selectedNode, nodeConfigs])

  const handleNodeClick = useCallback(
    (_: React.MouseEvent, node: Node) => {
      setSelectedNodeId(node.id)
    },
    [setSelectedNodeId],
  )

  const updateNodeData = useCallback(
    (nodeId: string, newData: Partial<any>) => {
      setNodes((nds) =>
        nds.map((node) => {
          if (node.id === nodeId) {
            return {
              ...node,
              data: {
                ...node.data,
                ...newData,
              },
            }
          }
          return node
        }),
      )
    },
    [setNodes],
  )

  const handleParameterChange = useCallback(
    (nodeId: string, parameterValues: any) => {
      updateNodeData(nodeId, { parameterValues })
    },
    [updateNodeData],
  )

  if (isLoading) {
    return (
      <div className="h-[calc(100vh-8rem)] flex items-center justify-center">
        <div className="text-center space-y-2">
          <div className="h-8 w-8 border-4 border-primary border-t-transparent rounded-full animate-spin mx-auto" />
          <p className="text-sm text-muted-foreground">加载中...</p>
        </div>
      </div>
    )
  }

  return (
    <div className="h-[calc(100vh-8rem)] flex flex-col gap-4">
      {/* Toolbar */}
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-4">
          <Input
            value={workflowName}
            onChange={(e) => setWorkflowName(e.target.value)}
            className="w-64 font-semibold"
            disabled={viewMode === "view"}
          />
          <Tabs value={workflowType} onValueChange={(v) => setWorkflowType(v as any)}>
            <TabsList>
              <TabsTrigger value="dify" disabled={viewMode === "view"}>
                Dify
              </TabsTrigger>
              <TabsTrigger value="coze" disabled={viewMode === "view"}>
                Coze
              </TabsTrigger>
              <TabsTrigger value="langgraph" disabled={viewMode === "view"}>
                LangGraph
              </TabsTrigger>
            </TabsList>
          </Tabs>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setViewMode(viewMode === "edit" ? "view" : "edit")}
          >
            {viewMode === "edit" ? (
              <>
                <Eye className="mr-2 h-4 w-4" />
                查看模式
              </>
            ) : (
              <>
                <Edit3 className="mr-2 h-4 w-4" />
                编辑模式
              </>
            )}
          </Button>
        </div>
        <div className="flex items-center gap-2">
          {workflowType === "langgraph" && (
            <>
              <Button variant="outline" size="sm" onClick={handleCopyCode}>
                <Copy className="mr-2 h-4 w-4" />
                复制代码
              </Button>
              <Button variant="outline" size="sm" onClick={handleExportCode}>
                <Download className="mr-2 h-4 w-4" />
                导出代码
              </Button>
            </>
          )}
          {workflowType !== "langgraph" && (
            <Button variant="outline" size="sm" onClick={handleViewGeneratedCode}>
              <Code2 className="mr-2 h-4 w-4" />
              查看分层代码
            </Button>
          )}
          <Button variant="outline" onClick={handleTest}>
            <Play className="mr-2 h-4 w-4" />
            测试运行
          </Button>
          {viewMode === "edit" && (
            <Button onClick={handleSave}>
              <Save className="mr-2 h-4 w-4" />
              保存
            </Button>
          )}
        </div>
      </div>

      {/* Main Content */}
      {workflowType === "langgraph" ? (
        <div className="flex-1 grid grid-cols-[1fr_320px] gap-4 min-h-0">
          <Card className="flex flex-col">
            <CardHeader className="pb-3">
              <CardTitle className="text-base">LangGraph 代码编辑器</CardTitle>
              <CardDescription>编写 LangGraph 工作流代码</CardDescription>
            </CardHeader>
            <CardContent className="flex-1 p-0">
              <Textarea
                value={langGraphCode}
                onChange={(e) => setLangGraphCode(e.target.value)}
                className="h-full font-mono text-sm resize-none rounded-none border-0 focus-visible:ring-0"
                placeholder="输入 LangGraph 代码..."
                disabled={viewMode === "view"}
              />
            </CardContent>
          </Card>

          <Card className="flex flex-col">
            <CardHeader className="pb-3">
              <CardTitle className="text-base">代码说明</CardTitle>
              <CardDescription>LangGraph 工作流指南</CardDescription>
            </CardHeader>
            <CardContent>
              <ScrollArea className="h-[calc(100vh-16rem)]">
                <div className="space-y-4 text-sm">
                  <div>
                    <h4 className="font-semibold mb-2">基本结构</h4>
                    <p className="text-muted-foreground">
                      LangGraph 工作流由状态图（StateGraph）、节点（Node）和边（Edge）组成。
                    </p>
                  </div>
                  <div>
                    <h4 className="font-semibold mb-2">定义状态</h4>
                    <code className="block bg-muted p-2 rounded text-xs">
                      class State(TypedDict):
                      <br />
                      &nbsp;&nbsp;messages: list[str]
                    </code>
                  </div>
                  <div>
                    <h4 className="font-semibold mb-2">添加节点</h4>
                    <code className="block bg-muted p-2 rounded text-xs">workflow.add_node("name", func)</code>
                  </div>
                  <div>
                    <h4 className="font-semibold mb-2">连接节点</h4>
                    <code className="block bg-muted p-2 rounded text-xs">workflow.add_edge("from", "to")</code>
                  </div>
                </div>
              </ScrollArea>
            </CardContent>
          </Card>
        </div>
      ) : (
        <div className="flex-1 grid grid-cols-[280px_1fr_360px] gap-4 min-h-0">
          {/* Node Library */}
          {viewMode === "edit" && (
            <Card className="flex flex-col">
              <CardHeader className="pb-3">
                <CardTitle className="text-base">节点库</CardTitle>
                <CardDescription>拖拽节点到画布</CardDescription>
              </CardHeader>
              <CardContent className="flex-1 p-0">
                <ScrollArea className="h-full px-4 pb-4">
                  <div className="space-y-4">
                    {Array.from(new Set(nodeConfigs.map((c) => c.category))).map((category) => (
                      <div key={category} className="space-y-2">
                        <h4 className="text-sm font-medium text-muted-foreground">{category}</h4>
                        <div className="space-y-1">
                          {nodeConfigs
                            .filter((config) => config.category === category)
                            .map((config) => {
                              const IconComponent = iconMap[config.iconName]
                              return (
                                <div
                                  key={config.id}
                                  draggable
                                  onDragStart={(e) => onDragStart(e, config)}
                                  className="group flex flex-col gap-2 p-3 rounded-lg border bg-card hover:bg-accent cursor-move transition-colors"
                                >
                                  <div className="flex items-center gap-3">
                                    <div className="h-8 w-8 rounded-md bg-primary/10 flex items-center justify-center flex-shrink-0">
                                      <IconComponent className="h-4 w-4 text-primary" />
                                    </div>
                                    <span className="text-sm font-medium">{config.label}</span>
                                  </div>
                                  {config.description && (
                                    <p className="text-xs text-muted-foreground leading-relaxed opacity-0 group-hover:opacity-100 transition-opacity">
                                      {config.description}
                                    </p>
                                  )}
                                </div>
                              )
                            })}
                        </div>
                      </div>
                    ))}
                  </div>
                </ScrollArea>
              </CardContent>
            </Card>
          )}

          {/* Canvas */}
          <Card className={`relative overflow-hidden ${viewMode === "edit" ? "" : "col-span-2"}`}>
            <ReactFlow
              nodes={nodes}
              edges={edges}
              onNodesChange={onNodesChange}
              onEdgesChange={onEdgesChange}
              onConnect={onConnect}
              onDrop={onDrop}
              onDragOver={onDragOver}
              onNodeClick={handleNodeClick}
              nodeTypes={nodeTypes}
              fitView
              nodesDraggable={viewMode === "edit"}
              nodesConnectable={viewMode === "edit"}
              elementsSelectable={viewMode === "edit"}
            >
              <Background />
              <Controls />
              <MiniMap
                nodeColor={(node) => {
                  const colors: Record<string, string> = {
                    trigger: "#3b82f6",
                    start: "#3b82f6",
                    llm: "#a855f7",
                    knowledge: "#10b981",
                    memory: "#10b981",
                    code: "#f97316",
                    condition: "#ec4899",
                    branch: "#ec4899",
                    default: "#6b7280",
                  }
                  return colors[node.data.type] || colors.default
                }}
                maskColor="rgb(0, 0, 0, 0.1)"
              />
              <Panel position="top-left">
                <Badge variant="outline" className="bg-background">
                  {viewMode === "edit" ? "编辑模式" : "查看模式"}
                </Badge>
              </Panel>
            </ReactFlow>
          </Card>

          {/* Properties Panel */}
          {viewMode === "edit" && (
            <Card className="flex flex-col">
              <CardHeader className="pb-3">
                <CardTitle className="text-base">节点属性</CardTitle>
                <CardDescription>配置选中节点</CardDescription>
              </CardHeader>
              <CardContent className="flex-1">
                {selectedNode && selectedNodeConfig ? (
                  <ScrollArea className="h-full pr-4">
                    <div className="space-y-4">
                      {/* 基本信息 */}
                      <div className="space-y-3">
                        <div className="space-y-2">
                          <Label>节点名称</Label>
                          <Input
                            value={selectedNode.data.label}
                            onChange={(e) => {
                              updateNodeData(selectedNode.id, { label: e.target.value })
                            }}
                          />
                        </div>
                        <div className="space-y-2">
                          <Label>节点类型</Label>
                          <Input value={selectedNodeConfig.label} disabled />
                        </div>
                        {selectedNodeConfig.description && (
                          <div className="flex gap-2 p-2 rounded-md bg-muted/50">
                            <Info className="h-4 w-4 text-muted-foreground shrink-0 mt-0.5" />
                            <p className="text-xs text-muted-foreground">{selectedNodeConfig.description}</p>
                          </div>
                        )}
                      </div>

                      <Separator />

                      {/* 输入参数 */}
                      {selectedNodeConfig.inputs.length > 0 && (
                        <NodeParameterEditor
                          parameters={selectedNodeConfig.inputs}
                          values={selectedNode.data.parameterValues || {}}
                          onChange={(values) => handleParameterChange(selectedNode.id, values)}
                          title="输入参数"
                          type="input"
                        />
                      )}

                      {/* 输出参数 */}
                      {selectedNodeConfig.outputs.length > 0 && (
                        <ParameterList parameters={selectedNodeConfig.outputs} title="输出参数" />
                      )}
                    </div>
                  </ScrollArea>
                ) : (
                  <div className="flex items-center justify-center h-full text-sm text-muted-foreground text-center px-4">
                    <div className="space-y-2">
                      <p>选择一个节点查看属性</p>
                      <p className="text-xs">点击节点可查看和编辑其属性</p>
                    </div>
                  </div>
                )}
              </CardContent>
            </Card>
          )}
        </div>
      )}
    </div>
  )
}
